// (c) 2008 Kickstone Technology Ltd

#include "stdafx.h"
#include "IEWindow.h"
#include <algorithm>
#include "RebarHandler.h"
#include "ButtonDemoBHO.h"

using namespace std;


// static variables
CCriticalSection CIEWindow::m_globalCS;
CIEWindow::WindowMap CIEWindow::m_Windows;


CIEWindow::CIEWindow(HWND hWnd) {
	m_hWnd=hWnd;
	m_rebarHandler=new CRebarHandler(hWnd, this);
	m_bhoCnt=0;
	m_currentBHO=NULL;
}

CIEWindow::~CIEWindow() {
	delete m_rebarHandler;
}

///////////////////////////////////////////////////////////////////////////
// BHO management
///////////////////////////////////////////////////////////////////////////
CButtonDemoBHO *CIEWindow::getCurrentBHO(){
	return m_currentBHO;
}

void CIEWindow::setCurrentBHO(CButtonDemoBHO *bho){
	m_currentBHO=bho;
}

// increment BHO count
void CIEWindow::addBHO(){
	ATLTRACE("CIEWindow::addBHO\n");
	m_cs.lock();
	m_bhoCnt++;
	m_cs.unlock();
}

// decrement BHO count and remove window if necessary
void CIEWindow::removeBHO(){
	ATLTRACE("CIEWindow::removeBHO\n");
	int cnt;
	m_cs.lock();
	cnt=--m_bhoCnt;
	m_cs.unlock();
	if (cnt==0){
		removeWindow(m_hWnd);
	}
}

///////////////////////////////////////////////////////////////////////////
// Window management
///////////////////////////////////////////////////////////////////////////

// find a window given the hWnd
CIEWindow *CIEWindow::findWindow(HWND hWnd){
	CIEWindow *ptr=NULL;
	m_globalCS.lock();
	WindowMap::iterator itr=m_Windows.find(hWnd);
	if (itr != m_Windows.end())
		ptr=itr->second;
	m_globalCS.unlock();
	return ptr;
}

// add the window to the list of managed windows if needed
CIEWindow *CIEWindow::addWindow(HWND hWnd){
	CIEWindow *ptr=NULL;
	m_globalCS.lock();
	WindowMap::iterator itr=m_Windows.find(hWnd);
	if (itr != m_Windows.end())
		ptr=itr->second;
	else {
		ptr=new CIEWindow(hWnd);
		m_Windows[hWnd]=ptr;
		ptr->m_rebarHandler->subclass();
	}
	m_globalCS.unlock();
	return ptr;
}

// remove and shutdown a main window from the list
void CIEWindow::removeWindow(HWND hWnd){
	ATLTRACE("CIEWindow::removeWindow\n");
	CIEWindow *ptr=NULL;
	m_globalCS.lock();
	WindowMap::iterator itr=m_Windows.find(hWnd);
	if (itr != m_Windows.end())
		ptr=itr->second;
	else {
		ATLTRACE("******* ERROR - Unable to find HWND to remove it ******\n");
		return;
	}
	m_Windows.erase(hWnd);
	ptr->m_rebarHandler->UnsubclassWindow();
	m_globalCS.unlock();
	delete ptr;
}
